<template>
	<view class="container">
		<!-- 顶部导航栏 -->
		<view class="cu-bar bg-white solid-bottom">
			<view class="action">
				<text class="cuIcon-title text-orange"></text> 定时任务管理
			</view>
			<view class="flex-sub text-right">
				<button class="cu-btn bg-green shadow" @tap="handleAdd">
					<text class="cuIcon-add"></text>新增
				</button>
			</view>
		</view>
		
		<!-- 搜索区域 -->
		<view class="cu-bar bg-white solid-bottom search-bar">
			<view class="action">
				<input v-model="queryParams.jobName" class="input-search" placeholder="请输入任务名称" />
			</view>
			<view class="action margin-left-sm">
				<button class="cu-btn bg-blue shadow" @tap="handleQuery">
					<text class="cuIcon-search"></text>搜索
				</button>
			</view>
			<view class="action margin-left-sm">
				<button class="cu-btn bg-grey shadow" @tap="resetQuery">
					<text class="cuIcon-refresh"></text>重置
				</button>
			</view>
		</view>
		
		<!-- 任务列表 -->
		<view class="job-list">
			<view class="cu-card case" v-for="(item,index) in jobList" :key="item.jobId">
				<view class="cu-item shadow">
					<view class="content" @tap="handleView(item)">
						<view class="job-header">
							<view class="job-title">
								<text class="text-bold">{{ item.jobName }}</text>
								<text class="text-sm text-gray margin-left-sm">[{{ getJobGroupName(item.jobGroup) }}]</text>
							</view>
							<view class="job-status">
								<text :class="item.status == '0' ? 'text-green' : 'text-red'">
									{{ item.status == '0' ? '运行中' : '已暂停' }}
								</text>
							</view>
						</view>
						<view class="job-info margin-top-xs">
							<view class="text-gray text-sm">
								<text class="cuIcon-title"></text>
								调用方法: {{ item.invokeTarget }}
							</view>
							<view class="text-gray text-sm margin-top-xs">
								<text class="cuIcon-time"></text>
								Cron表达式: {{ item.cronExpression }}
							</view>
							<view class="text-gray text-sm margin-top-xs" v-if="item.nextValidTime">
								<text class="cuIcon-timefill"></text>
								下次执行: {{ parseTime(item.nextValidTime) }}
							</view>
						</view>
					</view>
					<view class="job-actions">
						<switch :checked="item.status == '0'" @change="handleStatusChange($event, item)" />
						<button class="cu-btn round line-blue sm margin-left-sm" @tap.stop="handleRun(item)">
							<text class="cuIcon-playfill"></text>执行
						</button>
						<button class="cu-btn round line-orange sm margin-left-sm" @tap.stop="handleEdit(item)">
							<text class="cuIcon-edit"></text>编辑
						</button>
						<button class="cu-btn round line-red sm margin-left-sm" @tap.stop="handleDelete(item)">
							<text class="cuIcon-delete"></text>删除
						</button>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 空数据提示 -->
		<view v-if="jobList.length === 0 && !loading" class="empty-container">
			<view class="empty-content">
				<text class="cuIcon-info text-gray empty-icon"></text>
				<view class="text-gray margin-top">暂无定时任务数据</view>
			</view>
		</view>
		
		<!-- 添加或修改定时任务对话框 -->
		<view class="cu-modal job-modal" :class="{show: open}">
			<view class="cu-dialog job-dialog">
				<view class="cu-bar bg-white justify-end">
					<view class="content text-bold">{{ title }}</view>
					<view class="action" @tap="cancel">
						<text class="cuIcon-close text-red"></text>
					</view>
				</view>
				<view class="bg-white job-form">
					<view class="padding">
						<view class="cu-form-group">
							<view class="title">任务名称</view>
							<input v-model="form.jobName" placeholder="请输入任务名称" />
						</view>
						<view class="cu-form-group" @tap="showJobGroupPicker">
							<view class="title">任务分组</view>
							<view class="picker">
								{{ form.jobGroup ? getJobGroupName(form.jobGroup) : '请选择任务分组' }}
							</view>
						</view>
						<view class="cu-form-group">
							<view class="title">调用方法</view>
							<input v-model="form.invokeTarget" placeholder="请输入调用目标字符串" />
						</view>
						<view class="cu-form-group">
							<view class="title">Cron表达式</view>
							<input v-model="form.cronExpression" placeholder="请输入cron执行表达式" />
						</view>
						<view class="cu-form-group" @tap="showMisfirePolicyPicker">
							<view class="title">执行策略</view>
							<view class="picker">
								{{ form.misfirePolicy ? getMisfirePolicyName(form.misfirePolicy) : '请选择执行策略' }}
							</view>
						</view>
						<view class="cu-form-group" @tap="showConcurrentPicker">
							<view class="title">是否并发</view>
							<view class="picker">
								{{ form.concurrent ? getConcurrentName(form.concurrent) : '请选择是否并发' }}
							</view>
						</view>
						<view class="cu-form-group" v-if="form.jobId !== undefined" @tap="showStatusPicker">
							<view class="title">状态</view>
							<view class="picker">
								{{ form.status ? getStatusName(form.status) : '请选择状态' }}
							</view>
						</view>
					</view>
				</view>
				<view class="cu-bar bg-white justify-end">
					<view class="action">
						<button class="cu-btn line-grey" @tap="cancel">取消</button>
						<button class="cu-btn bg-green margin-left" @tap="submitForm">确定</button>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 任务详情对话框 -->
		<view class="cu-modal job-modal" :class="{show: openView}">
			<view class="cu-dialog job-dialog">
				<view class="cu-bar bg-white justify-end">
					<view class="content text-bold">任务详细</view>
					<view class="action" @tap="openView = false">
						<text class="cuIcon-close text-red"></text>
					</view>
				</view>
				<scroll-view class="bg-white" scroll-y style="max-height: 70vh;">
					<view class="padding">
						<view class="cu-form-group">
							<view class="title">任务编号:</view>
							<view>{{ form.jobId }}</view>
						</view>
						<view class="cu-form-group">
							<view class="title">任务名称:</view>
							<view>{{ form.jobName }}</view>
						</view>
						<view class="cu-form-group">
							<view class="title">任务分组:</view>
							<view>{{ getJobGroupName(form.jobGroup) }}</view>
						</view>
						<view class="cu-form-group">
							<view class="title">调用方法:</view>
							<view>{{ form.invokeTarget }}</view>
						</view>
						<view class="cu-form-group">
							<view class="title">Cron表达式:</view>
							<view>{{ form.cronExpression }}</view>
						</view>
						<view class="cu-form-group">
							<view class="title">下次执行时间:</view>
							<view>{{ parseTime(form.nextValidTime) || '无' }}</view>
						</view>
						<view class="cu-form-group">
							<view class="title">状态:</view>
							<view>
								<text :class="form.status == '0' ? 'text-green' : 'text-red'">
									{{ getStatusName(form.status) }}
								</text>
							</view>
						</view>
						<view class="cu-form-group">
							<view class="title">是否并发:</view>
							<view>{{ getConcurrentName(form.concurrent) }}</view>
						</view>
						<view class="cu-form-group">
							<view class="title">执行策略:</view>
							<view>{{ getMisfirePolicyName(form.misfirePolicy) }}</view>
						</view>
					</view>
				</scroll-view>
				<view class="cu-bar bg-white justify-end">
					<view class="action">
						<button class="cu-btn bg-green" @tap="openView = false">确定</button>
					</view>
				</view>
			</view>
		</view>
		
		<!-- 选择器弹窗 -->
		<view class="cu-modal bottom-modal" :class="{show: showPicker}">
			<view class="cu-dialog">
				<view class="cu-bar bg-white">
					<view class="action text-grey" @tap="cancelPicker">取消</view>
					<view class="action text-green" @tap="confirmPicker">确定</view>
				</view>
				<view class="picker-view">
					<picker-view :indicator-style="indicatorStyle" :value="pickerValue" @change="bindPickerChange">
						<picker-view-column>
							<view class="picker-item" v-for="(item,index) in pickerRange" :key="index">
								{{ item.label }}
							</view>
						</picker-view-column>
					</picker-view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import { listJob, getJob, delJob, addJob, updateJob, runJob, changeJobStatus } from '@/api/monitor/job.js'
	
	export default {
		data() {
			return {
				// 遮罩层
				loading: false,
				// 总条数
				total: 0,
				// 定时任务表格数据
				jobList: [],
				// 弹出层标题
				title: "",
				// 是否显示弹出层
				open: false,
				// 是否显示详细弹出层
				openView: false,
				// 查询参数
				queryParams: {
					pageNum: 1,
					pageSize: 10,
					jobName: undefined,
					jobGroup: undefined,
					status: undefined
				},
				// 表单参数
				form: {
					jobId: undefined,
					jobName: undefined,
					jobGroup: undefined,
					invokeTarget: undefined,
					cronExpression: undefined,
					misfirePolicy: undefined,
					concurrent: undefined,
					status: undefined
				},
				
				jobGroups: [],
				misfirePolicies: [],
				concurrents: [],
				statuses: [],
				
				// 选择器相关
				showPicker: false,
				pickerType: '', // 当前选择器类型
				pickerValue: [0],
				pickerRange: [],
				indicatorStyle: `height: 50px;`,
			}
		},
		created() {
			this.getList()
			this.initDictData()
		},
		methods: {
			/** 初始化字典数据 */
			initDictData() {
				// 初始化任务分组数据
				this.jobGroups = [
					{ value: "DEFAULT", label: "默认" },
					{ value: "SYSTEM", label: "系统" }
				];
				
				// 初始化执行策略数据
				this.misfirePolicies = [
					{ value: "1", label: "立即执行" },
					{ value: "2", label: "执行一次" },
					{ value: "3", label: "放弃执行" }
				];
				
				// 初始化是否并发数据
				this.concurrents = [
					{ value: "0", label: "允许" },
					{ value: "1", label: "禁止" }
				];
				
				// 初始化状态数据
				this.statuses = [
					{ value: "0", label: "正常" },
					{ value: "1", label: "暂停" }
				];
				
				// 设置表单默认值
				this.form.jobGroup = "DEFAULT";
				this.form.misfirePolicy = "1";
				this.form.concurrent = "1";
				this.form.status = "0";
			},
			
			/** 查询定时任务列表 */
			getList() {
				this.loading = true
				listJob(this.queryParams).then(response => {
					this.jobList = response.rows
					this.total = response.total
					this.loading = false
				}).catch(() => {
					this.loading = false
					this.$modal.msgError("获取任务列表失败")
				})
			},
			
			// 取消按钮
			cancel() {
				this.open = false
				this.reset()
			},
			
			// 表单重置
			reset() {
				this.form = {
					jobId: undefined,
					jobName: undefined,
					jobGroup: "DEFAULT",
					invokeTarget: undefined,
					cronExpression: undefined,
					misfirePolicy: "1",
					concurrent: "1",
					status: "0"
				}
			},
			
			getJobGroupName(value) {
				if (!value) return '请选择任务分组';
				const group = this.jobGroups.find(item => item.value === value);
				return group ? group.label : '请选择任务分组';
			},
			
			getStatusName(value) {
				if (!value) return '请选择状态';
				const status = this.statuses.find(item => item.value === value);
				return status ? status.label : '请选择状态';
			},
			
			getConcurrentName(value) {
				if (!value) return '请选择是否并发';
				const concurrent = this.concurrents.find(item => item.value === value);
				return concurrent ? concurrent.label : '请选择是否并发';
			},
			
			getMisfirePolicyName(value) {
				if (!value) return '请选择执行策略';
				const policy = this.misfirePolicies.find(item => item.value === value);
				return policy ? policy.label : '请选择执行策略';
			},
			
			getJobGroupIndex(value) {
				const index = this.jobGroups.findIndex(item => item.value === value)
				return index === -1 ? 0 : index
			},
			
			getMisfirePolicyIndex(value) {
				const index = this.misfirePolicies.findIndex(item => item.value === value)
				return index === -1 ? 0 : index
			},
			
			getConcurrentIndex(value) {
				const index = this.concurrents.findIndex(item => item.value === value)
				return index === -1 ? 0 : index
			},
			
			getStatusIndex(value) {
				const index = this.statuses.findIndex(item => item.value === value)
				return index === -1 ? 0 : index
			},
			
			parseTime(time) {
				if (!time) return ''
				// 如果是时间戳格式，需要转换
				if (typeof time === 'number') {
					const date = new Date(time)
					return date.toLocaleString()
				}
				return time
			},
			
			/** 搜索按钮操作 */
			handleQuery() {
				this.queryParams.pageNum = 1
				this.getList()
			},
			
			/** 重置按钮操作 */
			resetQuery() {
				this.queryParams.jobName = undefined
				this.handleQuery()
			},
			
			/** 新增按钮操作 */
			handleAdd() {
				this.reset()
				this.open = true
				this.title = "添加任务"
			},
			
			/** 修改按钮操作 */
			handleEdit(row) {
				getJob(row.jobId).then(response => {
					this.form = response.data
					this.open = true
					this.title = "修改任务"
				}).catch(() => {
					this.$modal.msgError("获取任务信息失败")
				})
			},
			
			/** 查看详情 */
			handleView(row) {
				getJob(row.jobId).then(response => {
					this.form = response.data
					this.openView = true
				}).catch(() => {
					this.$modal.msgError("获取任务信息失败")
				})
			},
			
			/** 提交按钮 */
			submitForm() {
				if (this.form.jobName === undefined || this.form.jobName.trim() === "") {
					this.$modal.msgError("任务名称不能为空")
					return
				}
				if (this.form.invokeTarget === undefined || this.form.invokeTarget.trim() === "") {
					this.$modal.msgError("调用目标字符串不能为空")
					return
				}
				if (this.form.cronExpression === undefined || this.form.cronExpression.trim() === "") {
					this.$modal.msgError("cron执行表达式不能为空")
					return
				}
				
				if (this.form.jobId !== undefined) {
					updateJob(this.form).then(response => {
						this.$modal.msgSuccess("修改成功")
						this.open = false
						this.getList()
					}).catch(() => {
						this.$modal.msgError("修改失败")
					})
				} else {
					addJob(this.form).then(response => {
						this.$modal.msgSuccess("新增成功")
						this.open = false
						this.getList()
					}).catch(() => {
						this.$modal.msgError("新增失败")
					})
				}
			},
			
			/* 立即执行一次 */
			handleRun(row) {
				this.$modal.confirm('确认要立即执行一次"' + row.jobName + '"任务吗？').then(res => {
					if(res) {
						runJob(row.jobId, row.jobGroup).then(() => {
							this.$modal.msgSuccess("执行成功")
							// 发送本地通知
							this.$notification.sendJobNotification(row.jobName, "任务已开始执行");
						}).catch(() => {
							this.$modal.msgError("执行失败")
							// 发送本地通知
							// this.$notification.sendJobNotification(row.jobName, "任务执行失败");
						})
					}
				})
			},
			
			// 任务状态修改
			handleStatusChange(e, row) {
				const newStatus = e.detail.value ? "0" : "1";
				const text = e.detail.value ? "启用" : "停用";
				
				this.$modal.confirm('确认要"' + text + '""' + row.jobName + '"任务吗？').then(res => {
					if(res) {
						changeJobStatus(row.jobId, newStatus).then(() => {
							this.$modal.msgSuccess(text + "成功")
							row.status = newStatus
							// 发送本地通知
							this.$notification.sendJobNotification(row.jobName, "任务已" + text);
						}).catch(() => {
							// 如果失败，则恢复开关状态
							row.status = row.status === "0" ? "1" : "0"
							this.$modal.msgError(text + "失败")
							// 发送本地通知
							this.$notification.sendJobNotification(row.jobName, "任务" + text + "失败");
						})
					} else {
						// 用户取消操作，恢复开关状态
						row.status = row.status === "0" ? "1" : "0"
					}
				})
			},
			
			// 删除任务
			handleDelete(row) {
				this.$modal.confirm('是否确认删除定时任务"' + row.jobName + '"？').then(res => {
					if(res) {
						delJob(row.jobId).then(() => {
							this.$modal.msgSuccess("删除成功")
							this.getList()
							// 发送本地通知
							// this.$notification.sendJobNotification(row.jobName, "任务已删除");
						}).catch(() => {
							this.$modal.msgError("删除失败")
							// 发送本地通知
							// this.$notification.sendJobNotification(row.jobName, "任务删除失败");
						})
					}
				})
			},
			
			// 显示任务分组选择器
			showJobGroupPicker() {
				this.pickerType = 'jobGroup'
				this.$set(this, 'pickerRange', this.jobGroups)
				const index = this.jobGroups.findIndex(item => item.value === this.form.jobGroup)
				this.pickerValue = [index === -1 ? 0 : index]
				this.showPicker = true
			},
			
			// 显示执行策略选择器
			showMisfirePolicyPicker() {
				this.pickerType = 'misfirePolicy'
				this.$set(this, 'pickerRange', this.misfirePolicies)
				const index = this.misfirePolicies.findIndex(item => item.value === this.form.misfirePolicy)
				this.pickerValue = [index === -1 ? 0 : index]
				this.showPicker = true
			},
			
			// 显示是否并发选择器
			showConcurrentPicker() {
				this.pickerType = 'concurrent'
				this.$set(this, 'pickerRange', this.concurrents)
				const index = this.concurrents.findIndex(item => item.value === this.form.concurrent)
				this.pickerValue = [index === -1 ? 0 : index]
				this.showPicker = true
			},
			
			// 显示状态选择器
			showStatusPicker() {
				this.pickerType = 'status'
				this.$set(this, 'pickerRange', this.statuses)
				const index = this.statuses.findIndex(item => item.value === this.form.status)
				this.pickerValue = [index === -1 ? 0 : index]
				this.showPicker = true
			},
			
			// 选择器值改变
			bindPickerChange(e) {
				this.pickerValue = e.detail.value
			},
			
			// 取消选择
			cancelPicker() {
				this.showPicker = false
				this.pickerType = ''
				this.pickerRange = []
			},
			
			// 确认选择
			confirmPicker() {
				if (this.pickerType && this.pickerRange.length > 0) {
					const selectedItem = this.pickerRange[this.pickerValue[0]]
					if (selectedItem) {
						this.form[this.pickerType] = selectedItem.value
					}
				}
				this.cancelPicker()
			}
		}
	}
</script>

<style lang="scss" scoped>
	.container {
		min-height: 100vh;
		background-color: #f5f5f5;
	}
	
	.search-bar {
		padding: 10rpx 20rpx;
	}
	
	.input-search {
		width: 300rpx;
		height: 60rpx;
		border: 1rpx solid #e0e0e0;
		border-radius: 10rpx;
		padding: 0 20rpx;
	}
	
	.job-list {
		padding: 20rpx;
	}
	
	.job-header {
		display: flex;
		justify-content: space-between;
		align-items: center;
	}
	
	.job-title {
		font-size: 32rpx;
	}
	
	.job-info {
		padding-left: 10rpx;
	}
	
	.job-actions {
		display: flex;
		align-items: center;
		justify-content: flex-end;
		padding: 20rpx;
		border-top: 1rpx solid #f0f0f0;
	}
	
	.job-dialog {
		width: 90%;
		max-width: 600rpx;
		border-radius: 20rpx;
		overflow: hidden;
	}
	
	.job-modal {
		z-index: 9999;
	}
	
	.job-form {
		max-height: 70vh;
		overflow-y: auto;
	}
	
	.empty-container {
		display: flex;
		justify-content: center;
		align-items: center;
		height: 60vh;
	}
	
	.empty-content {
		text-align: center;
	}
	
	.empty-icon {
		font-size: 100rpx;
	}
	
	.cu-form-group .title {
		min-width: 200rpx;
	}
	
	.cu-form-group {
		min-height: 80rpx;
	}
	
	.picker {
		flex: 1;
		padding-right: 30rpx;
		color: #666;
		text-align: right;
	}
	
	.picker-view {
		height: 400rpx;
		width: 100%;
	}
	
	.picker-item {
		text-align: center;
		line-height: 50px;
	}
	
	.bottom-modal {
		z-index: 10000;
	}
</style>